package com.bytz.modules.cms.domain.impl.price;

import cn.hutool.core.util.StrUtil;
import com.bytz.modules.cms.common.model.CategoryDiscountSearchVo;
import com.bytz.modules.cms.common.service.CmsCacheService;
import com.bytz.modules.cms.domain.model.price.PriceComputeContext;
import com.bytz.modules.cms.domain.model.price.PriceComputeResult;
import com.bytz.modules.cms.domain.util.PriceComputerUtil;
import com.bytz.modules.cms.product.entity.ProductDiscountCategoryLevel;
import com.bytz.modules.cms.reseller.service.IResellerLevelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 经销商限制产品计算器，顺序 5
 * @author shanxuezhong
 */
@Component
public class CategoryDiscountComputer extends AbstractPriceComputer {

    @Autowired
    private IResellerLevelService resellerLevelService;

    @Autowired
    private CmsCacheService cmsCacheService;

    @Override
    public void doCompute(PriceComputeContext context) {
        ensureResellerLevels(resellerLevelService, context);

        // 找出需要计算价格的产品，Map的Key是找折扣的Key，Value是产品的计算结果对象
        Map<CategoryDiscountSearchVo, List<PriceComputeResult>> needCalculateMap = context.getResults().values().stream()
                .filter(p -> p.getPrice() != null)
                .filter(p -> StrUtil.isNotBlank(p.getDiscountCategoryId()))
                .filter(p -> StrUtil.isNotBlank(p.getProductLineLevelId()))
                .collect(Collectors.groupingBy(k -> new CategoryDiscountSearchVo(k.getDiscountCategoryId(), k.getProductLineLevelId())));

        // 去查询折扣比例
        List<CategoryDiscountSearchVo> searchVos = new ArrayList<>(needCalculateMap.keySet());
        Map<CategoryDiscountSearchVo, ProductDiscountCategoryLevel> categoryDiscounts = cmsCacheService.getCategoryDiscounts(searchVos);

        for (Map.Entry<CategoryDiscountSearchVo, List<PriceComputeResult>> entry : needCalculateMap.entrySet()) {
            Optional.ofNullable(categoryDiscounts.get(entry.getKey()))
                    .map(ProductDiscountCategoryLevel::getDiscountRatio)
                    .ifPresent(discountRatio -> {
                        List<PriceComputeResult> priceComputeResults = entry.getValue();
                        priceComputeResults.forEach(value -> {
                            value.setCategoryDiscountRatio(discountRatio);
                            value.setPrice(PriceComputerUtil.scale(value.getPrice().multiply(discountRatio)));
                        });
                    });
        }
    }

    @Override
    public void afterCompute(PriceComputeContext context) {
        // 什么也不用做
    }
}
